<?php

/*
 * 
 * This file is part of importXMPmeta.

    importXMPMeta is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    importXMPMeta is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with importXMPMeta.  If not, see <http://www.gnu.org/licenses/>
 * 
 * importXMPMeta
 * V1.0 - february 2012
 * Copyright Eric Zapletal (http://code.google.com/p/xmputils/)
 * 
 */

/*
 * include customizeLegend() user function
 */
require 'custom.php';

function trace($level, $message) {

    if (!strcmp($level, "ERROR")) {
        die("ERROR :: " . $message . " !\n");
    } else {

        echo "<!-- " . $level . ", " . $message . " -->\n";
    }
}

if ($argc < 2) {
    trace("ERROR", "usage = " . $argv[0] . " BookFile [NewBookFile]");
}

$bookFile = $argv[1];

if (!file_exists($bookFile)) {
    trace("ERROR",  "Book file '" . $bookFile . "' does not exist");
}

// load XML data from Book file
$xml = simplexml_load_file($bookFile);

if ($xml == FALSE) {
    trace("ERROR" , "Invalid XML format for book file '" . $bookFile . "'");
}

// Init XMP framework
SXMPFiles::Initialize();

/*
 * modify the legend for the Image
 * 
 * the legend is a XML String element (in a XML serialized javabean object)
 * 
 * $sjo = serialized javabean object
 */

function modifyXMLLegend($sjo, $newLegend) {
    
    global $customLegendTextStyle;
    global $customLegendAlignment;

    $xpathLinkedList = "//java/object[@class='java.util.LinkedList']/void[@method='add']/object[@class='java.util.LinkedList']";
    $xpathHashMap = "//java/object[@class='java.util.LinkedList']/void[@method='add']/object[@class='java.util.HashMap']";

    $domDm = new DOMDocument();
    $domDm->loadXML($sjo);
    $xpath = new DOMXpath($domDm);

    $entries = $xpath->query($xpathLinkedList . "/void[@method='add']/string");
    $n = $entries->length;
    $i = 1;
    $modified = FALSE;

    foreach ($entries as $entry) {

        if (($i == $n) || (strlen(trim($entry->nodeValue)) > 0)) {
            $entry->nodeValue = $newLegend;
            $modified = TRUE;
            break;
        }
        $i++;
    }

    if ($modified == FALSE) {
        trace("WARNING", "unable to modify legend '" . $newLegend . "'");
    }

    // change text style
    $entries = $xpath->query($xpathHashMap . "/void[@method='put']/string[text()='resolver']/following-sibling::string");
    $n = $entries->length;
    if ($n == 1) {
        foreach ($entries as $entry) {
            $entry->nodeValue = $customLegendTextStyle . ".chars";
        }
    }
    else
        trace("WARNING", "unable to modify legend text style '" . $newLegend . "'");

    // change text alignment
    $entries = $xpath->query($xpathHashMap . "/void[@method='put']/string[text()='Alignment']/following-sibling::int");
    $n = $entries->length;
    if ($n == 1) {
        foreach ($entries as $entry) {
            $entry->nodeValue = $customLegendAlignment; // 1=center alignment
        }
    } else {
        // create alignment element

        $alignElem = new DOMDocument;
        $alignElem->loadXML('<void method="put"><string>Alignment</string><int>1</int></void>');
        $entries = $xpath->query($xpathHashMap);
        $n = $entries->length;
        foreach ($entries as $entry) {
            $alignElem = $domDm->importNode($alignElem->documentElement, true);
            $entry->appendChild($alignElem);
            break;
        }
    }

    return $domDm->saveXML();
}

/*
 * extract XMP metadata to build image legend
 *
 * sourceURI = URI to image file
 */

function createLegendFromXMPData($sourceURI) {

    // conver URL to file system compatible path name ('%20' -> ' ')
    $imageFileName = urldecode(substr($sourceURI, 5));

    if (!file_exists($imageFileName))
        trace("ERROR", "image file '" . $imageFileName . "' does not exist");

    // read metadata from file
    $xmpfiles = new SXMPFiles();
    $xmpmeta = new SXMPMeta();
    $xmpfiles->OpenFile($imageFileName);
    $xmpfiles->GetXMP($xmpmeta);

    $newLegend = customizeLegend($xmpmeta);

    $xmpfiles->CloseFile();

    return $newLegend;
}

/*
 * search an XML Element in the XML tree
 * 
 * $xml : xml data tree
 * $keyElement : name of the XML Element
 * $keyAtttribute : name of the attribute
 * $keyValue : attribute value
 */

function searchElementWithAttribute($xml, $keyElement, $keyAttribute, $keyValue) {

    if (!strcmp($xml->getName(), $keyElement)) {
        $att = $xml->attributes();
        $att_id = $att->$keyAttribute;
        if (!strcmp($att_id, $keyValue)) {
            return $xml;
        }
    }

    foreach ($xml->children() as $child) {
        $f = searchElementWithAttribute($child, $keyElement, $keyAttribute, $keyValue);
        if ($f != null)
            return $f;
    }

    return null;
}

$bookObjects = $xml->{"bookObjects"};

foreach ($bookObjects->children() as $child) {

    // search for a ImageFile XML object
    if (!strcmp($child->getName(), "ImageFile")) {

        // child = ImageList
        $att = $child->attributes();
        $sourceURI = $att->sourceURI;
        $id = $att->id;

        $newImageLegend = createLegendFromXMPData($sourceURI);

        // search for a ImageContent XML object that use the ImageFile
        $imageContent = searchElementWithAttribute($xml, "ImageContent", "content", $id);
        if ($imageContent != null) {

            $parentId = $imageContent->attributes()->parentId;
            // search for the TextContent XML object that has the same parent
            $textContent = searchElementWithAttribute($xml, "TextContent", "parentId", $parentId);

            if ($textContent != null) {
                $dm = $textContent->dm[0];
                $newDm = modifyXMLLegend($dm, $newImageLegend);
                $textContent->dm[0] = $newDm;
                // change text style to customize legend text style
                $textContent->attributes()->ts = $customLegendTextStyle;
                trace("INFO", $sourceURI . " : '" . $newImageLegend . "'");
            } else {
                // TextContent not found -> add a TextContent in the Book for this Image !
                trace("WARNING", "no text content for image '" . $sourceURI . "'");
            }
        }
    }
}

if ($argc == 3) {

    $newBookFile = $argv[2];

    if ($xml->asXML($newBookFile)) {
        trace("INFO", "new book file '" . $newBookFile . "' created");
    } else {
        trace("ERROR", "new book file '" . $newBookFile . "' can not be created");
    }
}
else
    echo $xml->asXML();
?>